/*
 *  $Id: Enchantment.cs 1233 2010-12-18 17:54:48Z thenn.erannor $
 *  This file is a part of Ragima CCG.
 *  (C) 2008-2010 Ragima development group.
 *
 *  Licensed under the terms of the GNU GPL License version 2.
 *
 */

using System;
using System.Collections.Generic;

using AgateLib;
using AgateLib.Geometry;

using Nereal.Extensions;
using Nereal.Serialization;

namespace Ragima {
    /// <summary>
    /// Тип цели: чары.
    /// </summary>
    public class EnchantmentTarget : TargetType {
        /// <summary>
        /// Цель: все чары.
        /// </summary>
        public static readonly EnchantmentTarget All = new EnchantmentTarget(new Languages.Phrase("target.enchantment.all"), false, null);
        /// <summary>
        /// Цель: развеиваемые чары.
        /// </summary>
        public static readonly EnchantmentTarget OnlyDispellable = new EnchantmentTarget(new Languages.Phrase("target.enchantment.dispellable"), true, null);

        private bool _dispellable;
        private TargetPredicate<Affect> _condition;

        public EnchantmentTarget(Languages.Phrase notice, bool dispellable, TargetPredicate<Affect> condition) : base(notice) {
            _dispellable = dispellable;
            _condition = condition;
        }

        public override bool IsRealTarget {
            get { return true; }
        }

        protected override void AutoSelectTab(Player player) {
            player.DefaultTab = TabType.Enchantments;
        }

        /// <summary>
        /// Число целей всегда равно 1, чтобы можно было выбрать.
        /// </summary>
        public override int GetCount(AbstractObject caster) {
            return 1;
        }

        /// <summary>
        /// Целевые регионы: чары
        /// </summary>
        public override bool AcceptRegion(Region region) {
            var er = region as EnchantmentRegion;
            if (er == null)
                return false;
            if (_dispellable)
                if (!er.Enchantment.Dispellable || !er.Enchantment.IsRoot || er.Enchantment.Owner.HasFlag<Affects.Antimagic>())
                    return false;
            if (_condition != null)
                if (!_condition(Request, er.Enchantment))
                    return false;
            return true;
        }

        public override TargetArgs GetArgs(Region region) {
            var er = region as EnchantmentRegion;
            return er != null ? new EnchantmentTargetArgs(Request.Player, Request.Caster, er.Enchantment) : null;
        }
    }

    [TypeId("enchant")]
    public class EnchantmentTargetArgs : TargetArgs<Affect> {
        [Serialize, XmlName("owner"), Reference(true, typeof(string), Serialization.Resolvers.GameObject)]
        private AbstractObject _owner;
        [Serialize, XmlName("enchant"), DefaultValue(-1)]
        private int _enchantNumber;

        public EnchantmentTargetArgs() {
        }
        public EnchantmentTargetArgs(Player player, AbstractObject caster, Affect target) : base(player, caster) {
            _owner = target != null ? target.Owner : null;
            _enchantNumber = _owner != null ? _owner.Summary.GetEnchantments().IndexOf(target) : -1;
        }

        public override Affect Target {
            get {
                if (_owner == null)
                    return null;
                var enchantments = _owner.Summary.GetEnchantments();
                return enchantments.GetOrDefault(_enchantNumber);
            }
        }
    }
}
